/**
 *  @file
 *  @brief   二阶张量Vogit形式坐标变换矩阵
 *  @author  wanghuan
 *  @date    2024.03.31
 *  @version  v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once
#include "Utility/Algebra/Matrix.h"

#include "DataStructure/Common/DataStructureNamespace.h"

SG_DATASTRUCTURE_NAMESPACE_OPEN

namespace FEM
{
    class TenserTranform
    {
      public:
        /** @brief 应变坐标变换矩阵
         *
         */
        static void StrainTrans (const SG::Algebra::Matrix& T33, SG::Algebra::Matrix& TEpsilon);
        /** @brief 应力坐标变换矩阵，应变坐标变换矩阵逆矩阵的转置
         *
         */
        static void StressTrans (const SG::Algebra::Matrix& T33, SG::Algebra::Matrix& TSigma);
    };

    inline void TenserTranform::StrainTrans (const SG::Algebra::Matrix& T33, SG::Algebra::Matrix& TEpsilon)
    {
        assert (3 == T33.GetColSize ());
        assert (3 == T33.GetRowSize ());

        TEpsilon        = SG::Algebra::Matrix (6, 6);
        TEpsilon (0, 0) = T33 (0, 0) * T33 (0, 0);
        TEpsilon (0, 1) = T33 (0, 1) * T33 (0, 1);
        TEpsilon (0, 2) = T33 (0, 2) * T33 (0, 2);
        TEpsilon (0, 3) = T33 (0, 0) * T33 (0, 1);
        TEpsilon (0, 4) = T33 (0, 1) * T33 (0, 2);
        TEpsilon (0, 5) = T33 (0, 2) * T33 (0, 0);

        TEpsilon (1, 0) = T33 (1, 0) * T33 (1, 0);
        TEpsilon (1, 1) = T33 (1, 1) * T33 (1, 1);
        TEpsilon (1, 2) = T33 (1, 2) * T33 (1, 2);
        TEpsilon (1, 3) = T33 (1, 0) * T33 (1, 1);
        TEpsilon (1, 4) = T33 (1, 1) * T33 (1, 2);
        TEpsilon (1, 5) = T33 (1, 2) * T33 (1, 0);

        TEpsilon (2, 0) = T33 (2, 0) * T33 (2, 0);
        TEpsilon (2, 1) = T33 (2, 1) * T33 (2, 1);
        TEpsilon (2, 2) = T33 (2, 2) * T33 (2, 2);
        TEpsilon (2, 3) = T33 (2, 0) * T33 (2, 1);
        TEpsilon (2, 4) = T33 (2, 1) * T33 (2, 2);
        TEpsilon (2, 5) = T33 (2, 2) * T33 (2, 0);

        TEpsilon (3, 0) = T33 (0, 0) * T33 (1, 0) * 2.0;
        TEpsilon (3, 1) = T33 (0, 1) * T33 (1, 1) * 2.0;
        TEpsilon (3, 2) = T33 (0, 2) * T33 (1, 2) * 2.0;
        TEpsilon (3, 3) = T33 (0, 0) * T33 (1, 1) + T33 (0, 1) * T33 (1, 0);
        TEpsilon (3, 4) = T33 (0, 1) * T33 (1, 2) + T33 (0, 2) * T33 (1, 1);
        TEpsilon (3, 5) = T33 (0, 2) * T33 (1, 0) + T33 (0, 0) * T33 (1, 2);

        TEpsilon (4, 0) = T33 (1, 0) * T33 (2, 0) * 2.0;
        TEpsilon (4, 1) = T33 (1, 1) * T33 (2, 1) * 2.0;
        TEpsilon (4, 2) = T33 (1, 2) * T33 (2, 2) * 2.0;
        TEpsilon (4, 3) = T33 (1, 0) * T33 (2, 1) + T33 (1, 1) * T33 (2, 0);
        TEpsilon (4, 4) = T33 (1, 1) * T33 (2, 2) + T33 (1, 2) * T33 (2, 1);
        TEpsilon (4, 5) = T33 (1, 2) * T33 (2, 0) + T33 (1, 0) * T33 (2, 2);

        TEpsilon (5, 0) = T33 (2, 0) * T33 (0, 0) * 2.0;
        TEpsilon (5, 1) = T33 (2, 1) * T33 (0, 1) * 2.0;
        TEpsilon (5, 2) = T33 (2, 2) * T33 (0, 2) * 2.0;
        TEpsilon (5, 3) = T33 (2, 0) * T33 (0, 1) + T33 (2, 1) * T33 (0, 0);
        TEpsilon (5, 4) = T33 (2, 1) * T33 (0, 2) + T33 (2, 2) * T33 (0, 1);
        TEpsilon (5, 5) = T33 (2, 2) * T33 (0, 0) + T33 (2, 0) * T33 (0, 2);
    }

    inline void TenserTranform::StressTrans (const SG::Algebra::Matrix& T33, SG::Algebra::Matrix& TSigma)
    {
        assert (3 == T33.GetColSize ());
        assert (3 == T33.GetRowSize ());

        TSigma        = SG::Algebra::Matrix (6, 6);
        TSigma (0, 0) = T33 (0, 0) * T33 (0, 0);
        TSigma (0, 1) = T33 (0, 1) * T33 (0, 1);
        TSigma (0, 2) = T33 (0, 2) * T33 (0, 2);
        TSigma (0, 3) = T33 (0, 0) * T33 (0, 1) * 2.0;
        TSigma (0, 4) = T33 (0, 1) * T33 (0, 2) * 2.0;
        TSigma (0, 5) = T33 (0, 2) * T33 (0, 0) * 2.0;

        TSigma (1, 0) = T33 (1, 0) * T33 (1, 0);
        TSigma (1, 1) = T33 (1, 1) * T33 (1, 1);
        TSigma (1, 2) = T33 (1, 2) * T33 (1, 2);
        TSigma (1, 3) = T33 (1, 0) * T33 (1, 1) * 2.0;
        TSigma (1, 4) = T33 (1, 1) * T33 (1, 2) * 2.0;
        TSigma (1, 5) = T33 (1, 2) * T33 (1, 0) * 2.0;

        TSigma (2, 0) = T33 (2, 0) * T33 (2, 0);
        TSigma (2, 1) = T33 (2, 1) * T33 (2, 1);
        TSigma (2, 2) = T33 (2, 2) * T33 (2, 2);
        TSigma (2, 3) = T33 (2, 0) * T33 (2, 1) * 2.0;
        TSigma (2, 4) = T33 (2, 1) * T33 (2, 2) * 2.0;
        TSigma (2, 5) = T33 (2, 2) * T33 (2, 0) * 2.0;

        TSigma (3, 0) = T33 (0, 0) * T33 (1, 0);
        TSigma (3, 1) = T33 (0, 1) * T33 (1, 1);
        TSigma (3, 2) = T33 (0, 2) * T33 (1, 2);
        TSigma (3, 3) = T33 (0, 0) * T33 (1, 1) + T33 (0, 1) * T33 (1, 0);
        TSigma (3, 4) = T33 (0, 1) * T33 (1, 2) + T33 (0, 2) * T33 (1, 1);
        TSigma (3, 5) = T33 (0, 2) * T33 (1, 0) + T33 (0, 0) * T33 (1, 2);

        TSigma (4, 0) = T33 (1, 0) * T33 (2, 0);
        TSigma (4, 1) = T33 (1, 1) * T33 (2, 1);
        TSigma (4, 2) = T33 (1, 2) * T33 (2, 2);
        TSigma (4, 3) = T33 (1, 0) * T33 (2, 1) + T33 (1, 1) * T33 (2, 0);
        TSigma (4, 4) = T33 (1, 1) * T33 (2, 2) + T33 (1, 2) * T33 (2, 1);
        TSigma (4, 5) = T33 (1, 2) * T33 (2, 0) + T33 (1, 0) * T33 (2, 2);

        TSigma (5, 0) = T33 (2, 0) * T33 (0, 0);
        TSigma (5, 1) = T33 (2, 1) * T33 (0, 1);
        TSigma (5, 2) = T33 (2, 2) * T33 (0, 2);
        TSigma (5, 3) = T33 (2, 0) * T33 (0, 1) + T33 (2, 1) * T33 (0, 0);
        TSigma (5, 4) = T33 (2, 1) * T33 (0, 2) + T33 (2, 2) * T33 (0, 1);
        TSigma (5, 5) = T33 (2, 2) * T33 (0, 0) + T33 (2, 0) * T33 (0, 2);
    }

};  // namespace FEM
SG_DATASTRUCTURE_NAMESPACE_CLOSE